unit uSBDUnit_LeakageDetector;
interface
uses uSBDUnit_MemoryManagement, Classes, uSBDUnit_TestNode_InternalSupport,
     uSBD_BaseTypes, uSBD_ServiceProvider;

type
TLeakageMeter = class( TSBD_RefCountedCommonBase, ILeakageDetector)
  private
    FReferenceAllocation: int64;
    FSuppress: integer;
    FisMonitoring: boolean;

    procedure EnterMonitoringSuppression;
    procedure LeaveMonitoringSuppression;

  public
    [Configuration] constructor Create;
    destructor  Destroy; override;

    procedure EnterMonitoring;
    function  LeaveMonitoring( var Leakage: int64): boolean;
    function  IsMonitoring: boolean;
    function  MonitoringSuppression: IInterface;
  end;

procedure RegisterServices( const Registrar: IServiceProvider);
// ^-- Registers (ILeakageDetector,'')

implementation







uses uSBDUnit_OldStyleMMState_LeakageDetector;
type
TMonitoringSuppression = class( TSBD_RefCountedCommonBase)
  private
    FOwner: TLeakageMeter;
  public
    [Configuration('uSBDUnit_LeakageDetector.MonitoringSuppression')] constructor Create;
    destructor Destroy; override;
  end;



procedure RegisterServices( const Registrar: IServiceProvider);
begin
if UseMemoryMetering then
    begin
    TLeakageMeter         .RegisterThis( Registrar, ILeakageDetector);
    TMonitoringSuppression.RegisterThis( Registrar, IInterface)
    end
  else
    TMMState_LeakageMeter.RegisterThis( Registrar, ILeakageDetector)
end;


{ TLeakageMeter }

constructor TLeakageMeter.Create;
begin
Assert( UseMemoryMetering, 'Wrong Memory Management Model!');
FReferenceAllocation := 0;
FSuppress := 0;
FisMonitoring := False
end;

destructor TLeakageMeter.Destroy;
begin
SuppressMemoryMetering( -FSuppress);
inherited;
end;

procedure TLeakageMeter.EnterMonitoring;
begin
FReferenceAllocation := ComputeNettAllocation;
FisMonitoring := True
end;

function TLeakageMeter.IsMonitoring: boolean;
begin
result := FisMonitoring
end;

function TLeakageMeter.LeaveMonitoring( var Leakage: int64): boolean;
begin
Leakage := ComputeNettAllocation - FReferenceAllocation;
result  := Leakage = 0;
FisMonitoring := False
end;

procedure TLeakageMeter.EnterMonitoringSuppression;
begin
SuppressMemoryMetering( +1);
Inc( FSuppress)
end;

procedure TLeakageMeter.LeaveMonitoringSuppression;
begin
SuppressMemoryMetering( -1);
Dec( FSuppress)
end;

function TLeakageMeter.MonitoringSuppression: IInterface;
begin
AcquireService( IInterface, result, 'uSBDUnit_LeakageDetector.MonitoringSuppression')
end;

{ TMonitoringSuppression }

constructor TMonitoringSuppression.Create;
begin
//??FOwner := TObject( Client) as TLeakageMeter;
FServiceProvider := nil
end;

destructor TMonitoringSuppression.Destroy;
begin
FOwner.LeaveMonitoringSuppression;
inherited
end;


end.
